<?php  if (!defined('BASEPATH')) exit('No direct script access allowed');

/**
 * Установщик сайта
 *
 * @package CoreFramework
 * @version 1.0
 * @author Gennadiy Kozlenko
 */
class Install extends Controller {
     
    /**
     * Сообщение в виде HTML кода
     *
     * @access private
     * @var string
     */
    var $_message = '';
    
    /**
     * Поля
     */
    var $_db_host = 'localhost';
    var $_db_name = '';
    var $_db_user = '';
    var $_db_pass = '';
    var $_site_name = '';
    var $_site_email = '';
    var $_site_slogan = '';
    var $_admin_password = '';
    var $_license = '';
    
    /**
     * Крон скрипты
     * @var array
     */
    var $_cron = array(
        '0 */2 * * * php {%fcpath%}cron/cron.php --run=/cron_parser --server={%host%} > /dev/null 2>&1',
        '50 */2 * * * php {%fcpath%}cron/cron.php --run=/cron_partners --server={%host%} > /dev/null 2>&1',
        '30 3 * * * php {%fcpath%}cron/cron.php --run=/cron_sitemap --server={%host%} > /dev/null 2>&1'
    );
    
    /**
     * Каталоги, которые нужно отчмодить
     * @var array
     */
    var $_dirs = array(
        '{%fcpath%}data',
        '{%fcpath%}styles',
        '{%fcpath%}system/cache',
        '{%fcpath%}system/logs',
        '{%fcpath%}system/application/views/en/layouts',
    	'{%fcpath%}system/application/views/en/advertisments',
        '{%fcpath%}sitemap.xml'
    );
    
    /**
     * Установочные файлы
     * @var array
     */
    var $_install_files = array(
        '{%fcpath%}data/install',
        '{%fcpath%}system/application/controllers/install.php'
    );
    
    /**
     * Конструктор класса
     *
     * @access public
     * @return Install
     */
    function Install() {
        parent::Controller();
        $this->load->language('install');
    } // end Install
     
    /**
     * Метод по умолчанию
     *
     * @access public
     */
    function index() {
        if ($this->config->item('installed')) {
            // Если уже установили скрипт, редиректим на главную страницу
            redirect('front');
        }
        $data = array();
        // Валидируем и, если нужно, изменяем

        if (isset($_SERVER['HTTP_HOST']) && $_SERVER['HTTP_HOST']) {
            $this->_license = $_SERVER['HTTP_HOST'];
        } elseif (isset($_SERVER['SERVER_NAME']) && $_SERVER['SERVER_NAME']) {
            $this->_license = $_SERVER['SERVER_NAME'];
        } else {
            $this->_license = $_SERVER['REMOTE_ADDR'];
        }
        
        if (false !== $this->input->post('edit')) {
            $this->load->library('validation');
            $rules = array(
                'db_host'     => 'trim|required',
                'db_name'     => 'trim|required',
                'db_user'     => 'trim|required',
                'db_pass'     => 'trim',
                'site_name'   => 'trim|required',
                'site_slogan' => 'trim',
                'site_email'  => 'trim|required|valid_email',
                'license'     => 'trim',
            );
            $this->validation->set_rules($rules);
            $result = $this->validation->run();
            // Получаем из поста поля
            $this->_db_host = $this->validation->db_host;
            $this->_db_name = $this->validation->db_name;
            $this->_db_user = $this->validation->db_user;
            $this->_db_pass = '';
            if (isset($this->validation->db_pass)) {
                $this->_db_pass = $this->validation->db_pass;
            }
            $this->_site_name = $this->validation->site_name;
            $this->_site_slogan = '';
            if (isset($this->validation->site_slogan)) {
                $this->_site_slogan = $this->validation->site_slogan;
            }
            $this->_site_email = $this->validation->site_email;
            if (isset($this->validation->license)) {
                $this->_license = $this->validation->license;
            }
            if ($result) {
                if ($this->_install()) {
                    $this->redirect('install', 'welcome');
                }
            }
        }
        // Забиваем в дату поля
        $data['base_url'] = $this->getBaseUrl();
        $data['page_message'] = $this->get_message();
        $data['db_host'] = htmlspecialchars($this->_db_host);
        $data['db_name'] = htmlspecialchars($this->_db_name);
        $data['db_user'] = htmlspecialchars($this->_db_user);
        $data['db_pass'] = htmlspecialchars($this->_db_pass);
        $data['site_name'] = htmlspecialchars($this->_site_name);
        $data['site_slogan'] = htmlspecialchars($this->_site_slogan);
        $data['site_email'] = htmlspecialchars($this->_site_email);
        $data['license'] = htmlspecialchars($this->_license);
        // Обрабатываем ошибки
        $template = $this->parser->parse('common/error.html', array(), true);
        foreach ($this->errors->get_errors() as $key => $val) {
            $data['error_' . $key] = str_replace('{%content%}', $val, $template);
        }
        $this->parser->parse('install/body.html', $data);
    } // end index
    
    /**
     * Сообщение об успешной инсталяции и дополниьтельные настройки
     */
    function welcome() {
        $data = array(
            'base_url'       => base_url(),
            'admin_password' => $this->session->get('admin_password'),
            'cron'           => implode('<br />', $this->_cron),
            'dirs'           => implode('<br />', $this->_dirs),
            'install_files'  => implode('<br />', $this->_install_files),
            'fcpath'         => FCPATH,
            'host'           => $this->input->server('HTTP_HOST')
        );
        $this->parser->parse('install/welcome.html', $data);
    }
    
    /**
     * Установка скрипта
     */
    function _install() {
        $this->load->helper('string');
        
        // 0. Проверяем нужные файлы на запись
        $files = array(
            APPPATH . 'config/config.php',
            APPPATH . 'config/database.php',
            APPPATH . 'config/routes.php',
            APPPATH . 'config/system.php'
        );
        foreach ($files as $file) {
            if (!is_writable($file)) {
                $this->set_message(sprintf($this->lang->line('write_dir_fail'), dirname($file)), 'error');
                return false;
            }
        }
        
        // 1. Разбираемся с конфигом config.php
        $content = file_get_contents(APPPATH . 'config/config.php');
        $content = preg_replace('~\$config\[\'base_url\'\]\s*=\s*"[^"]*";~msi', '$config[\'base_url\'] = "' . $this->getBaseUrl() . '";', $content);
        $content = preg_replace('~\$config\[\'encryption_key\'\]\s*=\s*"[^"]*";~msi', '$config[\'encryption_key\'] = "' . random_string('alnum', 32) . '";', $content);
        if (false === file_put_contents(APPPATH . 'config/config.php', $content)) {
            $this->set_message(sprintf($this->lang->line('write_dir_fail'), APPPATH . 'config'), 'error');
            return false;
        }
        
        // 2. Разбираемся с конфигом database.php
        $content = file_get_contents(APPPATH . 'config/database.php');
        $content = preg_replace('~\$db\[\'default\'\]\[\'hostname\'\]\s*=\s*"[^"]*";~msi', '$db[\'default\'][\'hostname\'] = "' . $this->_db_host . '";', $content);
        $content = preg_replace('~\$db\[\'default\'\]\[\'username\'\]\s*=\s*"[^"]*";~msi', '$db[\'default\'][\'username\'] = "' . $this->_db_user . '";', $content);
        $content = preg_replace('~\$db\[\'default\'\]\[\'password\'\]\s*=\s*"[^"]*";~msi', '$db[\'default\'][\'password\'] = "' . $this->_db_pass . '";', $content);
        $content = preg_replace('~\$db\[\'default\'\]\[\'database\'\]\s*=\s*"[^"]*";~msi', '$db[\'default\'][\'database\'] = "' . $this->_db_name . '";', $content);
        if (false === file_put_contents(APPPATH . 'config/database.php', $content)) {
            $this->set_message(sprintf($this->lang->line('write_dir_fail'), APPPATH . 'config'), 'error');
            return false;
        }
        
        // 3. Проверяем доступ к базе данных
        $this->load->database('default');
        if (false === $this->db->conn_id) {
            $this->set_message($this->lang->line('db_connect_fail'), 'error');
            return false;
        }
        if (false === $this->db->db_select()) {
            $this->set_message(sprintf($this->lang->line('db_select_fail'), $this->_db_name), 'error');
            return false;
        }
        
        // 4. Загружаем в базу данных данные
        $content = file_get_contents(BASEPATH . '../data/install/database.sql');
        $lines = array_filter(array_map('trim', explode(';;', $content)));
        foreach ($lines as $sql) {
            $this->db->query($sql);
        }
        
        // 5. Вносим в базу данных некоторые настройки
        $this->load->library('variables');
        $this->variables->set('site_name', $this->_site_name);
        $this->variables->set('site_email', $this->_site_email);
        $this->variables->set('site_slogan', $this->_site_slogan);
        
        // 6. Меняем контроллер по умолчанию
        $content = file_get_contents(APPPATH . 'config/routes.php');
        $content = preg_replace('~\$route\[\'default_controller\'\]\s*=\s*"[^"]*";~msi', '$route[\'default_controller\'] = "front";', $content);
        if (false === file_put_contents(APPPATH . 'config/routes.php', $content)) {
            $this->set_message(sprintf($this->lang->line('write_dir_fail'), APPPATH . 'config'), 'error');
            return false;
        }
        
        // 7. Помечаем что мы закончили установку
        $content = file_get_contents(APPPATH . 'config/system.php');
        $content = preg_replace('~\$config\[\'installed\'\]\s*=\s*[^;]*;~msi', '$config[\'installed\'] = true;', $content);
        if (false === file_put_contents(APPPATH . 'config/system.php', $content)) {
            $this->set_message(sprintf($this->lang->line('write_dir_fail'), APPPATH . 'config'), 'error');
            return false;
        }
        
        // 8. Генерим пароль администратора
        $this->_admin_password = random_string('alnum', 8);
        $this->variables->set('admin_password', md5($this->_admin_password));
        $this->session->set('admin_password', $this->_admin_password);
        // Отправляем
        $e_data = array(
            'base_url'       => $this->getBaseUrl(),
            'admin_password' => $this->_admin_password
        );
        
        $subject = '';
        $content = '';
        $e_data['site_name'] = $this->variables->get('site_name');
        if (get_email('install', $subject, $content, $e_data)) {
            // Высылаем мыло
            $this->load->plugin('phpmailer');
            $mail = new PHPMailer();
            $mail->Mailer = 'mail';
            $mail->CharSet = 'utf-8';
            $mail->ContentType = 'text/html';
            $mail->From = 'videotracker@' . getenv('HTTP_HOST');
            $mail->FromName = 'HWD VideoTracker';
            $mail->AddAddress($this->_site_email);
            $mail->Subject = $subject;
            $mail->Body = $content;
            $mail->Send();
        }
        
        // 9. Активируем
        $this->load->library('license');
        $this->license->activate($this->_license, $this->_site_email);
         
        return true;
    }

    /**
     * Установка сообщения
     *
     * @access public
     * @param string $message Сообщение
     * @param string $type    Тип сообщения
     * @param boolean $store  Сохранять ли в сессии?
     */
    function set_message($message, $type = 'info', $store = false) {
        $data = array(
            'message' => $message,
            'type'    => $type,
        );
        $this->_message = $this->parser->parse('common/message.html', $data, true);
        if ($store) {
            $this->session->set('message', $this->_message);
        }
    } // end set_message
    
    /**
     * Получение сообщения в виде HTML кода
     *
     * @access public
     * @return string
     */
    function get_message() {
        if ($this->session->exists('message')) {
            $this->_message = $this->session->get('message');
            $this->session->clean('message');
        }
        return $this->_message;
    } // end get_message

    /**
     * Get base_url
     */
    function getBaseUrl() {
        return 'http://' . $this->input->server('HTTP_HOST') . $this->input->server('REQUEST_URI');
    }

   /**
    * Редирект на внутреннюю страницу
    *
    * @access public
    * @param string $class
    * @param string $method
    * @param array $params
    */
   function redirect($class = '', $method = '', $params = array()) {
      $this->load->helper('link');
      $url = create_link($class, $method, $params);
      header('Location: ' . $url);
      exit;
   } // end redirect
   
   /**
    * Редирект на внешнюю страницу
    *
    * @access public
    * @param string $url
    */
   function go($url) {
      header('Location: ' . $url);
      exit;
   } // end go
   
   /**
     * Output content
     * @param $output
     */
    function _output($output) {
        $output = preg_replace('~{%.*?%}~ms', '', $output);
        echo $output;
    }
    
}
